home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Collections: Camelot
/
Camelot 059 (1989-12)(Swedish User Group of Amiga)(SE)(PD)[WB].zip
/
Camelot 059 (1989-12)(Swedish User Group of Amiga)(SE)(PD)[WB].adf
/
Utils
/
du.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-11-14
|
5KB
|
227 lines
#include <exec/types.h>
#include <string.h>
#include <proto/exec.h>
#include <proto/dos.h>
#include <libraries/dos.h>
BPTR stdin, stdout;
int subdisp = TRUE, verbose = FALSE;
char *error_message[] = {
"No default directory", /* 201 */
"Object in use",
"Object exists",
"Directory not found",
"Object not found",
"Bad stream name",
"Object too large",
"Unknown error 208",
"Action not known",
"Invalid component name",
"Invalid lock",
"Object is of wrong type",
"Disk not validated",
"Disk write protected",
"Rename across devices",
"Directory not empty",
"Too many levels",
"Device not mounted",
"Seek error",
"Comment too big",
"Disk full",
"Delete protected",
"Write protected",
"Read protected",
"Not a DOS disk",
"No disk"
};
void MemCleanup() { }
void disp_error(int err, char *s)
{
printf("%ls -- ", s);
if (err >= 201 && err <= 226)
printf(error_message[err - 201]);
else
switch (err) {
case 0:
printf("No error!!!");
break;
case ERROR_NO_FREE_STORE:
printf("No free store");
break;
case ERROR_NO_MORE_ENTRIES:
printf("No more entries");
break;
default:
printf("Unknown error %ld", err);
break;
}
putchar('\n');
}
char *pathcat(to,from)
register char to[], from[];
{
register int l;
l = strlen(to) - 1;
if (l < 0 || to[l] == ':' || to[l] == '/')
strcat(to,from);
else
strcat(strcat(to, "/"), from);
return (to);
}
struct FileInfoBlock *GetInfo(char *name, long access, BPTR *lock)
{
struct FileInfoBlock *fib;
*lock = Lock(name, access);
if (*lock == NULL)
return (NULL);
fib = (struct FileInfoBlock *)AllocMem(sizeof(struct FileInfoBlock), 0);
if (fib == NULL) {
UnLock(*lock);
return (NULL);
}
if (Examine(*lock, fib)) return (fib);
return (NULL);
}
void FreeInfo(struct FileInfoBlock *fib, BPTR lock)
{
FreeMem((char *)fib, sizeof(struct FileInfoBlock));
UnLock(lock);
}
int check_size(char *name, long *bytes, long *blocks, long *files, int display)
{
struct FileInfoBlock *fib;
BPTR l;
int err = 0;
long byt = 0, blk = 0, fil = 0;
fib = GetInfo(name, SHARED_LOCK, &l);
if (fib == NULL)
return (IoErr());
if (fib->fib_DirEntryType > 0) /* Directory */
{
while (err == 0 && ExNext(l, fib)) /* Scan all files */
{
byt += fib->fib_Size;
blk += fib->fib_NumBlocks + 1;
if (fib->fib_DirEntryType > 0) /* File is a directory */
{
int len = strlen(name) + strlen(fib->fib_FileName) + 2;
char *newname = AllocMem(len, 0);
if (newname)
{
pathcat(strcpy(newname, name), fib->fib_FileName);
err = check_size(newname, &byt, &blk, &fil, subdisp);
FreeMem(newname, len);
}
else err = ERROR_NO_FREE_STORE;
}
else fil++;
}
}
else
{
byt = fib->fib_Size;
blk = fib->fib_NumBlocks + 1;
fil = 1;
}
if (err == 0) err = IoErr();
FreeInfo(fib, l);
if (err != ERROR_NO_MORE_ENTRIES) {
return (err);
}
if (display)
{
char *dirname = *name ? name : ".";
if (verbose)
printf("%ls: %ld bytes, approximately %ld blocks in %ld files\n",
dirname, byt, blk, fil);
else
printf("%ld\t%ls\n", blk, dirname);
}
*bytes += byt;
*blocks += blk;
*files += fil;
return 0;
}
/* du [-s] [-v] [names] */
int analyse_opts(int argc, char **argv, int *nargc, char ***nargv)
{
char *pname = *argv;
argv++;
argc--;
while (argc != 0 && **argv == '-')
{
if ((*argv)[2] == '\0')
switch ((*argv)[1])
{
case 's':
subdisp = FALSE;
break;
case 'v':
verbose = TRUE;
break;
default:
goto help;
}
else
goto help;
argv++; argc--;
}
*nargc = argc; *nargv = argv;
return TRUE;
help:
printf("Usage: %ls [-s] [-v] [names]\n", pname);
return FALSE;
}
void main(int argc, char *argv[])
{
int err;
long bytes = 0, blocks = 0, files = 0;
stdin = Input();
stdout = Output();
if (analyse_opts(argc, argv, &argc, &argv))
{
if (argc == 0)
err = check_size("", &bytes, &blocks, &files, TRUE);
else
do
{
bytes = blocks = files = 0;
err = check_size(*argv, &bytes, &blocks, &files, TRUE);
}
while ((argv++, --argc) && err == 0);
if (err) disp_error(err, "failed");
}
}